#pragma once
#include <stdafx.h>
#include <QObject>
#include "PointCloudBase.h"


#include <mutex>  
#include "KinectDataCollection.h"
class DataAnalysis :public QObject, public PointCloudBase
{
	Q_OBJECT
	#define POINT_CLOUD_SCALE 2
	#define CLUSTER_DISTANCE 0.04f*POINT_CLOUD_SCALE
public:

	struct suKinectData
	{
		KinectDataCollection::suDepthData m_Depth2D;
	//	PPointCloudDef m_pPntClound;
		vector<bool> m_isValid;
		cv::Mat m_colorData;
		PPointCloudDef m_pFacePnt;
		Eigen::Matrix4Xf m_matFace;
	};

	struct suResData
	{

		PPointCloudDef m_pHeadData;
		cv::Mat m_ImgData;
		KinectDataCollection::suDepthData m_Depth2D;
		cv::Point2f m_pntEllipseMiddle;
		cv::Size m_pntEllipseLength;
	};

	struct suHeadData
	{
		suHeadData(CameraSpacePoint pntBase, const Eigen::Quaternion<float>& ori, PPointCloudDef pHeadData, PPointCloudDef pFaceData)
		{
			m_pntFaceBase = pntBase;
			m_veFaceOrientation = ori;
			m_pHeadData = pHeadData;
			m_pFaceData = pFaceData;
		}
		CameraSpacePoint		m_pntFaceBase;
		Eigen::Quaternion<float> m_veFaceOrientation;

		PPointCloudDef m_pHeadData;
		PPointCloudDef m_pFaceData;
	};
	DataAnalysis();
	~DataAnalysis();

	bool GetCurrentData(suResData&data, bool isRemove = true)
	{
		bool ret = false;
		m_dataLock.lock();
		if (!m_vResData.empty())
		{
			data = *(m_vResData.begin());
			ret = true;
			if (isRemove)
			{
				m_vResData.erase(m_vResData.begin());
			}
		}
		m_dataLock.unlock();
		return ret;
	}

	void Start()
	{
		m_vHeadData.clear();
		m_faceScope.width = m_faceScope.height = 0;
	//	emit sign_CalMeshFinal();
	}
	void Stop();

	void StartCollect();

	shared_ptr<pcl::PolygonMesh> GetFinalMesh()
	{
		/*	shared_ptr<pcl::PolygonMesh> pmesh = shared_ptr<pcl::PolygonMesh>(new pcl::PolygonMesh());
			LoadMeshAsBin("SaveData\\mesh.bin", *pmesh);
			return pmesh;*/
		return m_pMesh;
	
	}

protected slots:
void ProgressChange(float fNewProgressValue, QString strInfo)
{
	emit sign_ProgressChange(fNewProgressValue, strInfo);
}
signals:
	void sign_ResDataArrived();

	void sign_CalMeshFinal();

	void sign_ProgressChange(float fNewProgressValue, QString strInfo);
protected:
	shared_ptr<pcl::PolygonMesh> m_pMesh;
	void RunCalRes();
	bool IsFaceTransformEnough(const Eigen::Quaternion<float>& oriBefore, const Eigen::Quaternion<float>& oriNow, float dDetal=0.005);
	void ReveiceDataMain();
	void ReveiceData();
	std::vector<pair<int, int>>GetRegion(int x, int y, int iWidth, int iHeight);
	
	PPointCloudDef ExtractHeadData(const suKinectData& data);
	PPointCloudDef ExtractHeadRegion(const suKinectData& data);
	PCLPoint ToPCLPoint(const CameraSpacePoint& camPnt);

	cv::Mat HandleImage(const suKinectData& data);
	KinectDataCollection::suDepthData FilterData(const KinectDataCollection::suDepthData& dataIn);
private:
	atomic<int> m_threadRun;
	cv::Size m_faceScope;
	cv::Point2f m_faceMiddle;
	list<suKinectData> m_vlsData;
	std::mutex m_dataLock, m_headLock;
	list<suResData> m_vResData;
	list<suHeadData> m_vHeadData;
};

